﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace CellarDoor.Gui.Elements
{
    public class UiScrollBar : UiElement
    {
        #region Fields
        int repeatTimer = 0;
        int repeatFrequency = 25;
        int repeatDelay = 500;
        bool isRepeating;
        bool doRepeat;
        private float stepSize = 0.05f; 
        private UiButton buttonUp;
        private UiButton buttonDown;
        private UiSlideBar slideBar;
        #endregion

        #region Properties
        /// <summary>
        /// 
        /// </summary>
        public UiOrientation BarStyle
        {
            get { return slideBar.BarStyle; }
            set { slideBar.BarStyle = value; }
        }

        /// <summary>
        /// Gets the button for left/up (horizontal/vertical) step
        /// </summary>
        public UiButton ButtonUp
        {
            get { return buttonUp; }
        }

        /// <summary>
        /// Gets the button for right/down (horizontal/vertical) step
        /// </summary>
        public UiButton ButtonDown
        {
            get { return buttonDown; }
        }

        /// <summary>
        /// Gets or sets the stepsize. Default is 0.05f
        /// </summary>
        public float StepSize
        {
            get { return stepSize; }
            set { stepSize = value; }
        }

        /// <summary>
        /// Gets or sets the frequency of how fast the value is scrolled up/down
        /// when a user presses the scrollbuttons for a longer time. Default is 25ms
        /// </summary>
        public int RepeatFrequency
        {
            get { return repeatFrequency; }
            set { repeatFrequency = value; }
        }

        /// <summary>
        /// Gets or sets the delay after that the bar scrolls automaticly
        /// when a user presses the scrollbuttons for a longer time. Default is 500ms
        /// </summary>
        public int RepeatDelay
        {
            get { return repeatDelay; }
            set { repeatDelay = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public float Value
        {
            get { return slideBar.Value; }
            set { slideBar.Value = value; }
        }

        public event EventHandler ValueChanged;

        #endregion

        #region Constructor
        /// <summary>
        /// Creates a scroll bar control.
        /// </summary>
        public UiScrollBar()
            : base()
        {
            Initialize();
        }

        /// <summary>
        /// Creates a scroll bar control.
        /// </summary>
        public UiScrollBar(UiElement element)
            : base(element)
        {
            Initialize();
        }

        private void Initialize()
        {
            buttonUp = new UiButton(this);
            buttonUp.Click += Decrease;

            buttonDown = new UiButton(this);
            buttonDown.Click += Increase;

            slideBar = new UiSlideBar(this);
            slideBar.BarStyleChanged += new EventHandler(slideBar_BarStyleChanged);
            slideBar.ValueChanged += new EventHandler(slideBar_ValueChanged);

            slideBar_BarStyleChanged(this, null);

            this.Size = new Vector2(25, 200);
            this.buttonUp.Size = new Vector2(25);
            this.buttonDown.Size = new Vector2(25);
        }

        void slideBar_ValueChanged(object sender, EventArgs e)
        {
            if (ValueChanged != null)
            {
                ValueChanged(this, EventArgs.Empty);
            }
        }
        #endregion

        #region Methods
        void slideBar_BarStyleChanged(object sender, EventArgs e)
        {
            if (BarStyle == UiOrientation.Vertical)
            {
                slideBar.ElementName = "ScrollBarV";
                slideBar.Button.ElementName = "ScrollBallV";
                buttonUp.ElementName = "ButtonUp";
                buttonDown.ElementName = "ButtonDown";

                slideBar.Dock = UiDockStyles.Fill;
                buttonUp.Dock = UiDockStyles.Top;
                buttonDown.Dock = UiDockStyles.Bottom;
            }
            else
            {
                slideBar.ElementName = "ScrollBarH";
                slideBar.Button.ElementName = "ScrollBallH";
                buttonUp.ElementName = "ButtonLeft";
                buttonDown.ElementName = "ButtonRight";

                slideBar.Dock = UiDockStyles.Fill;
                buttonUp.Dock = UiDockStyles.Left;
                buttonDown.Dock = UiDockStyles.Right;
            }
        }

        private void Decrease(object sender, EventArgs e)
        {
            Value = Value - stepSize;
            if (Value <= 0)
            {
                Value = 0;
            }
        }

        private void Increase(object sender, EventArgs e)
        {
            Value = Value + stepSize;
            if (Value >= 1)
            {
                Value = 1;
            }
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            if (buttonDown.Style.State == UiVisualState.Down ||
                buttonUp.Style.State == UiVisualState.Down)
            {
                repeatTimer += gameTime.ElapsedGameTime.Milliseconds;

                if (!isRepeating && repeatTimer > repeatDelay)
                {
                    isRepeating = true;
                    repeatTimer = 0;
                }

                if (isRepeating)
                {
                    if (repeatTimer > repeatFrequency)
                    {
                        doRepeat = true;
                        repeatTimer = 0;
                    }
                    else
                    {
                        doRepeat = false;
                    }
                }
            }
            else
            {
                isRepeating = false;
                doRepeat = false;
                repeatTimer = 0;
            }

            if (buttonDown.Style.State == UiVisualState.Down && Value >= 1)
            {
                isRepeating = false;
                doRepeat = false;
                repeatTimer = 0;
                Value = 1;
            }

            if (buttonUp.Style.State == UiVisualState.Down && Value <= 0)
            {
                isRepeating = false;
                doRepeat = false;
                repeatTimer = 0;
                Value = 0;
            }

            if (doRepeat)
            {
                if (buttonUp.Style.State == UiVisualState.Down)
                {
                    slideBar.Value = slideBar.Value - stepSize;
                }

                if (buttonDown.Style.State == UiVisualState.Down)
                {
                    slideBar.Value = slideBar.Value + stepSize;
                }
            }
        }
        #endregion
    }
}
